package org.hepeng.workx.spring.orm;

import org.apache.commons.collections.MapUtils;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Map;
import java.util.concurrent.Callable;

/**
 * @author he peng
 */
public class TXSyncResourcesConcurrentSupport {

    private static Map<Object , Object> txSyncResourceMap = TransactionSynchronizationManager.getResourceMap();

    private static void refreshTxSyncResources() {
        TXSyncResourcesConcurrentSupport.txSyncResourceMap = TransactionSynchronizationManager.getResourceMap();
    }

    private static void bindTXSyncResources() {
        if (MapUtils.isNotEmpty(TXSyncResourcesConcurrentSupport.txSyncResourceMap)) {
            for (Map.Entry<Object, Object> entry : TXSyncResourcesConcurrentSupport.txSyncResourceMap.entrySet()) {
                TransactionSynchronizationManager.bindResource(entry.getKey() , entry.getValue());
            }
        }
    }

    public static abstract class TXSyncResourcesCallable<V> implements Callable<V> {

        public TXSyncResourcesCallable() {
            TXSyncResourcesConcurrentSupport.refreshTxSyncResources();
        }

        @Override
        public V call() throws Exception {
            bindTXSyncResources();
            return internalCall();
        }

        protected abstract V internalCall() throws Exception;
    }

    public static abstract class TXSyncResourcesRunnable implements Runnable {

        public TXSyncResourcesRunnable() {
            TXSyncResourcesConcurrentSupport.refreshTxSyncResources();
        }

        @Override
        public void run() {
            bindTXSyncResources();
            internalRun();
        }

        protected abstract void internalRun();
    }
}
